home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ASTVariableDeclaration.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  7.9 KB  |  230 lines  |  [TEXT/KAHL]

  1. /* ASTVariableDeclaration.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTVariableDeclaration.h"
  31. #include "ASTExpression.h"
  32. #include "SymbolTableEntry.h"
  33. #include "TrashTracker.h"
  34. #include "Memory.h"
  35. #include "PromotableTypeCheck.h"
  36.  
  37.  
  38. struct ASTVarDeclRec
  39.     {
  40.         SymbolRec*                    SymbolTableEntry;
  41.         ASTExpressionRec*        InitializationExpression;
  42.         long                                LineNumber;
  43.     };
  44.  
  45.  
  46. /* allocate a new variable declaration.  if the Initializer expression is NIL, then */
  47. /* the object is initialized to NIL or zero when it enters scope. */
  48. ASTVarDeclRec*            NewVariableDeclaration(struct SymbolRec* SymbolTableEntry,
  49.                                             struct ASTExpressionRec* Initializer,
  50.                                             struct TrashTrackRec* TrashTracker, long LineNumber)
  51.     {
  52.         ASTVarDeclRec*        VarDecl;
  53.  
  54.         CheckPtrExistence(SymbolTableEntry);
  55.         CheckPtrExistence(Initializer);
  56.         VarDecl = (ASTVarDeclRec*)AllocTrackedBlock(sizeof(ASTVarDeclRec),TrashTracker);
  57.         if (VarDecl == NIL)
  58.             {
  59.                 return NIL;
  60.             }
  61.         SetTag(VarDecl,"ASTVarDeclRec");
  62.  
  63.         VarDecl->LineNumber = LineNumber;
  64.         VarDecl->SymbolTableEntry = SymbolTableEntry;
  65.         VarDecl->InitializationExpression = Initializer;
  66.  
  67.         return VarDecl;
  68.     }
  69.  
  70.  
  71. /* type check the variable declaration node.  this returns eCompileNoError if */
  72. /* everything is ok, and the appropriate type in *ResultingDataType. */
  73. CompileErrors                TypeCheckVariableDeclaration(DataTypes* ResultingDataType,
  74.                                             ASTVarDeclRec* VariableDeclaration, long* ErrorLineNumber,
  75.                                             struct TrashTrackRec* TrashTracker)
  76.     {
  77.         CompileErrors            Error;
  78.  
  79.         CheckPtrExistence(VariableDeclaration);
  80.         CheckPtrExistence(TrashTracker);
  81.  
  82.         if (VariableDeclaration->InitializationExpression == NIL)
  83.             {
  84.                 /* no initializer -- default */
  85.                 *ResultingDataType = GetSymbolVariableDataType(
  86.                     VariableDeclaration->SymbolTableEntry);
  87.                 return eCompileNoError;
  88.             }
  89.          else
  90.             {
  91.                 DataTypes                    InitializerType;
  92.                 DataTypes                    VariableType;
  93.  
  94.                 /* initializer checking */
  95.                 VariableType = GetSymbolVariableDataType(VariableDeclaration->SymbolTableEntry);
  96.                 Error = TypeCheckExpression(&InitializerType,
  97.                     VariableDeclaration->InitializationExpression,ErrorLineNumber,TrashTracker);
  98.                 if (Error != eCompileNoError)
  99.                     {
  100.                         return Error;
  101.                     }
  102.                 if (!CanRightBeMadeToMatchLeft(VariableType,InitializerType))
  103.                     {
  104.                         *ErrorLineNumber = VariableDeclaration->LineNumber;
  105.                         return eCompileTypeMismatchInAssignment;
  106.                     }
  107.                 if (MustRightBePromotedToLeft(VariableType,InitializerType))
  108.                     {
  109.                         ASTExpressionRec*        PromotedInitializer;
  110.  
  111.                         /* promote the initializer */
  112.                         PromotedInitializer = PromoteTheExpression(InitializerType/*orig*/,
  113.                             VariableType/*desired*/,VariableDeclaration->InitializationExpression,
  114.                             VariableDeclaration->LineNumber,TrashTracker);
  115.                         if (PromotedInitializer == NIL)
  116.                             {
  117.                                 *ErrorLineNumber = VariableDeclaration->LineNumber;
  118.                                 return eCompileOutOfMemory;
  119.                             }
  120.                         VariableDeclaration->InitializationExpression = PromotedInitializer;
  121.                         /* sanity check */
  122.                         Error = TypeCheckExpression(&InitializerType/*obtain new right type*/,
  123.                             VariableDeclaration->InitializationExpression,ErrorLineNumber,
  124.                             TrashTracker);
  125.                         ERROR((Error != eCompileNoError),PRERR(ForceAbort,
  126.                             "TypeCheckVariableDeclaration:  type promotion caused failure"));
  127.                     }
  128.                 ERROR(VariableType != InitializerType,PRERR(ForceAbort,
  129.                     "TypeCheckVariableDeclaration:  after type promotion, types are no"
  130.                     " longer the same"));
  131.                 *ResultingDataType = InitializerType;
  132.                 return eCompileNoError;
  133.             }
  134.         EXECUTE(PRERR(ForceAbort,"TypeCheckVariableDeclaration:  control reached end"));
  135.     }
  136.  
  137.  
  138. /* generate code for a variable declaration. returns True if successful, or */
  139. /* False if it fails. */
  140. MyBoolean                        CodeGenVarDecl(struct PcodeRec* FuncCode,
  141.                                             long* StackDepthParam, ASTVarDeclRec* VariableDeclaration)
  142.     {
  143.         long                            StackDepth;
  144.  
  145.         CheckPtrExistence(FuncCode);
  146.         CheckPtrExistence(VariableDeclaration);
  147.         StackDepth = *StackDepthParam;
  148.  
  149.         /* evaluate the value initializer expression if there is one */
  150.         if (VariableDeclaration->InitializationExpression != NIL)
  151.             {
  152.                 /* there's a true initializer */
  153.                 if (!CodeGenExpression(FuncCode,&StackDepth,
  154.                     VariableDeclaration->InitializationExpression))
  155.                     {
  156.                         return False;
  157.                     }
  158.             }
  159.          else
  160.             {
  161.                 /* generate the default zero value for this type */
  162.                 switch (GetSymbolVariableDataType(VariableDeclaration->SymbolTableEntry))
  163.                     {
  164.                         default:
  165.                             EXECUTE(PRERR(ForceAbort,"CodeGenVarDecl:  bad variable type"));
  166.                             break;
  167.                         case eBoolean:
  168.                         case eInteger:
  169.                         case eFixed:
  170.                             if (!AddPcodeInstruction(FuncCode,epLoadImmediateInteger,NIL))
  171.                                 {
  172.                                     return False;
  173.                                 }
  174.                             if (!AddPcodeOperandInteger(FuncCode,0))
  175.                                 {
  176.                                     return False;
  177.                                 }
  178.                             break;
  179.                         case eFloat:
  180.                             if (!AddPcodeInstruction(FuncCode,epLoadImmediateFloat,NIL))
  181.                                 {
  182.                                     return False;
  183.                                 }
  184.                             if (!AddPcodeOperandFloat(FuncCode,0))
  185.                                 {
  186.                                     return False;
  187.                                 }
  188.                             break;
  189.                         case eDouble:
  190.                             if (!AddPcodeInstruction(FuncCode,epLoadImmediateDouble,NIL))
  191.                                 {
  192.                                     return False;
  193.                                 }
  194.                             if (!AddPcodeOperandDouble(FuncCode,0))
  195.                                 {
  196.                                     return False;
  197.                                 }
  198.                             break;
  199.                         case eArrayOfBoolean:
  200.                         case eArrayOfInteger:
  201.                         case eArrayOfFloat:
  202.                         case eArrayOfDouble:
  203.                         case eArrayOfFixed:
  204.                             if (!AddPcodeInstruction(FuncCode,epLoadImmediateNILArray,NIL))
  205.                                 {
  206.                                     return False;
  207.                                 }
  208.                             break;
  209.                     }
  210.                 StackDepth += 1;
  211.             }
  212.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  213.             "CodeGenVarDecl:  stack depth error after evaluting initializer"));
  214.  
  215.         /* save the index of the stack into the variable thing yah */
  216.         SetSymbolVariableStackLocation(VariableDeclaration->SymbolTableEntry,StackDepth);
  217.  
  218.         /* duplicate the value so there's something to return */
  219.         if (!AddPcodeInstruction(FuncCode,epDuplicate,NIL))
  220.             {
  221.                 return False;
  222.             }
  223.         StackDepth += 1;
  224.         ERROR(StackDepth != *StackDepthParam + 2,PRERR(ForceAbort,
  225.             "CodeGenVarDecl:  stack depth error after duplicating value for return"));
  226.  
  227.         *StackDepthParam = StackDepth;
  228.         return True;
  229.     }
  230.